package com.xjrsoft.module.workflow.controller;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xjrsoft.common.result.Response;
import com.xjrsoft.core.secure.XjrUser;
import com.xjrsoft.core.secure.utils.SecureUtil;
import com.xjrsoft.core.tool.utils.*;
import com.xjrsoft.module.base.dto.GetPageListDto;
import com.xjrsoft.module.base.entity.XjrBaseDataItemDetail;
import com.xjrsoft.module.base.entity.XjrBaseTempfield;
import com.xjrsoft.module.base.entity.XjrBaseUser;
import com.xjrsoft.module.base.service.*;
import com.xjrsoft.module.base.vo.UserVo;
import com.xjrsoft.module.form.entity.XjrFormScheme;
import com.xjrsoft.module.form.entity.XjrFormSchemeInfo;
import com.xjrsoft.module.form.service.IXjrFormSchemeInfoService;
import com.xjrsoft.module.form.service.IXjrFormSchemeService;
import com.xjrsoft.module.form.vo.FormSchemeInfoVo;
import com.xjrsoft.module.workflow.dto.GetPageListNwfTaskDto;
import com.xjrsoft.module.workflow.entity.XjrNwfSchemeinfo;
import com.xjrsoft.module.workflow.mapper.NwfTaskMapper;
import com.xjrsoft.module.workflow.service.*;
import com.xjrsoft.module.workflow.vo.NwfSchemeInfoVo;
import io.jsonwebtoken.lang.Collections;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;

@Slf4j
@ControllerAdvice
@RestController
@RequestMapping("/workflow-task")
@Api(value = "工作流任务控制器", tags = "工作流任务控制器")
@AllArgsConstructor
public class NwfTaskController {

    private final IXjrNwfTaskService nwfTaskService;

    private final RuntimeService runtimeService;

    private final TaskService taskService;

    private final HistoryService historyService;

    private final IXjrFormSchemeInfoService formSchemeInfoService;

    private final IXjrFormSchemeService formSchemeService;

    private final IXjrNwfSchemeService nwfSchemeService;

    private final IXjrBaseTempfieldService tempfieldService;

    private final IXjrBaseUserRelationService userRelationService;

    private final IXjrBaseUserService userService;

    private final IXjrNwfSchemeInfoService nwfschemeinfoService;

    private final IXjrNwfSchemeAuthService nwfSchemeAuthService;

    private final IXjrNwfRelationService nwfRelationServicel;

    private final FormService formService;

    private final IXjrBaseDataItemDetailService dataItemDetailService;

    private final IXjrBaseTempfieldService xjrBaseTempfieldService;

    private final NwfTaskMapper nwfTaskMapper;

    private final IXjrBaseModuleService baseModuleService;

    private final RepositoryService repositoryService;


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/17
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:待办任务查询
     */
    @SneakyThrows
    @GetMapping("/upcoming-task")
    @ApiOperation(value = "待办任务查询")
    public Response upcomingTasks(GetPageListNwfTaskDto dto) {
        return Response.ok(nwfTaskService.upcomingTasks(SecureUtil.getUserId(), dto));
    }

    @SneakyThrows
    @GetMapping("/upcoming-task-count")
    @ApiOperation(value = "待办任务数量查询")
    public Response upcomingTasks() {
        return Response.ok(nwfTaskService.getupcomingTaskCount(SecureUtil.getUserId()));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/17
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:已办任务查询
     */
    @SneakyThrows
    @GetMapping("/history-task")
    @ApiOperation(value = "已办任务查询")
    public Response getHistoryTask(GetPageListNwfTaskDto dto) {
        return Response.ok(nwfTaskService.getHistoryTask(SecureUtil.getUserId(), dto));
    }

    @SneakyThrows
    @GetMapping("/history-task-count")
    @ApiOperation(value = "已办任务数量查询")
    public Response getHistoryTaskCount() {
        return Response.ok(nwfTaskService.getHistoryTaskCount(SecureUtil.getUserId()));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/27
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:我的任务
     */
    @SneakyThrows
    @GetMapping("/my-task")
    @ApiOperation(value = "我的任务查询")
    public Response myTask(GetPageListNwfTaskDto dto) {
        return Response.ok(nwfTaskService.myTask(SecureUtil.getUserId(), dto));
    }


    @SneakyThrows
    @GetMapping("/my-task-count")
    @ApiOperation(value = "我的任务数量查询")
    public Response myTask() {
        return Response.ok(nwfTaskService.myTaskCount(SecureUtil.getUserId()));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/27
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:我的传阅
     */
    @SneakyThrows
    @GetMapping("/manual-task")
    @ApiOperation(value = "我的传阅查询")
    public Response manualTask(GetPageListNwfTaskDto dto) {
        return Response.ok(nwfTaskService.manualTask(SecureUtil.getUserId(), dto));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/27
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:我的传阅
     */
    @SneakyThrows
    @GetMapping("/manual-task-count")
    @ApiOperation(value = "我的传阅数量查询")
    public Response manualTaskCount() {
        return Response.ok(nwfTaskService.manualTaskCount(SecureUtil.getUserId()));
    }


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/3
     * @Param:[processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:流转记录
     */
    @GetMapping("/history-taskList")
    @ApiOperation(value = "流转记录查询")
    @ApiImplicitParam(name = "processInstanceId", required = true, dataType = "string", paramType = "query", value = "流程实例id")
    public Response historyTaskList(String processInstanceId, boolean isPersonalTask) throws Exception {
        return Response.ok(nwfTaskService.historyTaskList(processInstanceId, isPersonalTask));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/3
     * @Param:[id:流程设计ID]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取流程表单信息
     */
    @SneakyThrows
    @GetMapping("/create-processform")
    @ApiOperation(value = "获取流程表单信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", dataType = "string", paramType = "query", value = "流程模板id"),
            @ApiImplicitParam(name = "nwfRelationId", dataType = "string", paramType = "query", value = "流程关联对象id")
    })
    public Response createprocessForm(@RequestParam("id") String id, @RequestParam(value = "nwfRelationId") String nwfRelationId) throws Exception {
        JSONObject result = nwfTaskService.createprocessForm(id, nwfRelationId);
        return Response.ok(result.getJSONArray("formDate"), result.getString("message"));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/5
     * @Param:[]
     * @return:com.xjrsoft.common.result.Response
     * @Description:创建流程
     */
    @SneakyThrows
    @PostMapping("/create-process")
    @ApiOperation(value = "创建流程")
    public Response createProcess(@RequestBody JSONObject formValueMap) throws Exception {
        // schemeInfo主键
        String fId = formValueMap.getString("F_Id");
        // 获取当前登录用户
        XjrUser currentUser = SecureUtil.getUser();
        // 数据id主键
        String keyValue = formValueMap.getString("keyValue");
        // 关联任务数组 [{流程模板id,流程实例id},{}]
        JSONArray relationTaskListStr = formValueMap.getJSONArray("relationTaskList");
        if (StringUtils.isNotBlank(fId)) {
            XjrNwfSchemeinfo xjrNwfSchemeinfo = nwfschemeinfoService.getById(fId);
            if (xjrNwfSchemeinfo != null) {
                String fDeploymentId = xjrNwfSchemeinfo.getDeploymentId();
                // 提交表单,创建流程实例
                JSONObject retMap = FlowableUtil.startProcessInstance(fDeploymentId, currentUser.getUserId(), keyValue, nwfSchemeService.getBySchemeInfoId(fId));
                String retCode = retMap.getString("retCode");
                if (StringUtils.equals(retCode, "0")) {
                    String processInstanceId = retMap.getString("processInstanceId");
                    // 保存关联任务信息
                    if (!Collections.isEmpty(relationTaskListStr)) {
                        XjrBaseTempfield xjrTempKeyvalue = new XjrBaseTempfield();
                        xjrTempKeyvalue.setId(StringUtil.randomUUID());
                        xjrTempKeyvalue.setFkey(fDeploymentId + StringPool.UNDERSCORE + processInstanceId);
                        xjrTempKeyvalue.setType("6");
                        xjrTempKeyvalue.setFvalue(relationTaskListStr.toJSONString());
                        tempfieldService.save(xjrTempKeyvalue);
                    }
                }
                return Response.ok(retMap, retMap.getString("message"));
            }
        }
        return Response.status(false);
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/3
     * @Param:[processInstanceId]
     * @return:void
     * @Description:查看按钮接口:返回流程图信息
     */
    @GetMapping("/view-process")
    @ApiOperation(value = "查看按钮接口:返回流程图信息")
    @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id")
    @SneakyThrows
    public void viewProcess(String processInstanceId) {
        HttpServletResponse response = WebUtil.getResponse();
        String fileName = FlowableUtil.getProccessImage(processInstanceId);
        File file = new File(fileName);
        if (!file.exists()) {
            String projectPath = IoUtil.getProjectPath();
            file = FileUtil.file(fileName);
        }
        if (file == null) {
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                String result = objectMapper.writeValueAsString(Response.notOk("文件不存在！"));
                response.getOutputStream().write(result.getBytes());
                return;
            } catch (JsonProcessingException e) {
                log.error(e.getMessage(), e);
            }
        } else {
            // 设置下载文件名
            response.setHeader("Content-Disposition", "inline;fileName=\"" + new String((file.getName()).getBytes("utf-8"), "ISO8859-1") + "\"");
            FileUtil.writeToStream(file, response.getOutputStream());
        }
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/3
     * @Param:[processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取任务表单
     */
    @SneakyThrows
    @GetMapping("/task-form")
    @ApiOperation(value = "获取任务表单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "任务id"),
            @ApiImplicitParam(name = "isMyTask", dataType = "string", paramType = "query", value = "是否是我的任务")
    })
    public Response getTaskForm(@RequestParam(value = "taskId", required = false) String taskId, @RequestParam(value = "isMyTask", defaultValue = "false") String isMyTask) throws Exception {
        // 当前登录用户Id
        String currentUserId = SecureUtil.getUserId();
        JSONArray retList = new JSONArray();
        String startBusinessKey = "";
        String processInstanceId = "";
        String deployId = "";
        String version = "";
        //当前最新的节点id
        String activityId = null;
        HistoricProcessInstance historicProcessInstance = null;
        if (StringUtil.isBlank(taskId)) {
            return Response.ok(retList);
        }
        // 根据任务id获取流程实例
//         获取bussinessKey
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        if (historicTaskInstance == null) {
            historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(taskId).singleResult();
            if (historicProcessInstance != null) {
                processInstanceId = historicProcessInstance.getId();
                List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().desc().list();
                if (CollectionUtil.isNotEmpty(list)) {
                    activityId = list.get(0).getActivityId();
                    if(activityId.contains("Flow")){
                        activityId=list.get(1).getActivityId();
                    }
                }
            }
        } else {
            activityId = historicTaskInstance.getTaskDefinitionKey();
            processInstanceId = historicTaskInstance.getProcessInstanceId();
            historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        }
        String nwfSchemeInfoId = "";
        if (historicProcessInstance != null) {
            startBusinessKey = historicProcessInstance.getBusinessKey();
            deployId = historicProcessInstance.getDeploymentId();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
            nwfSchemeInfoId = processDefinition.getDescription();
            version = String.valueOf(processDefinition.getVersion());
        } else {
            return Response.notOk("流程不存在");
        }
        Set<HistoricTaskInstance> taskInstancesList = new HashSet<>();
        if (StringUtil.equals(isMyTask, "true")) {
            Set<HashMap<String, Object>> nodeSet = new HashSet<>();
            //获取所有已办的任务
            String startActivitiId = "";
            //获取该节点之前的节点
            nodeSet.addAll(FlowableUtil.getAllNode(activityId, processInstanceId, 2, new TreeSet<>()));
            //获取该节点之后的节点
            nodeSet.addAll(FlowableUtil.getAllNode(activityId, processInstanceId, 1, new TreeSet<>()));
            for (HashMap<String, Object> nodeInfo : nodeSet) {
                String activitiId = nodeInfo.get("activitiId").toString();
                String activityType = nodeInfo.get("activityType").toString();
                if (StringUtil.equals(activityType, "startEvent")) {
                    startActivitiId = activitiId;
                    continue;
                }
                taskInstancesList.addAll(historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).taskDefinitionKey(activitiId).finished().list());
            }
            //获取开始节点的表单信息
            if (StringUtil.equals(historicProcessInstance.getStartUserId(), currentUserId)) {
                XjrBaseTempfield startFormInfo = xjrBaseTempfieldService.getByIdAndType(processInstanceId + StringPool.UNDERSCORE + startActivitiId, "25");
                if (startFormInfo != null) {
                    String businessKey = startFormInfo.getFvalue();
                    if (StringUtils.isNotBlank(businessKey)) {
                        String startActivityId = historicProcessInstance.getStartActivityId();
                        String key = nwfSchemeInfoId + StringPool.UNDERSCORE + startActivityId + StringPool.UNDERSCORE + version;
                        XjrBaseTempfield xjrBaseTempfield = xjrBaseTempfieldService.getByIdAndType(key, "3");
                        if (xjrBaseTempfield != null) {
                            JSONArray jsonArray = JSON.parseArray(xjrBaseTempfield.getFvalue());
                            JSONArray keyList = JSONObject.parseArray(businessKey);
                            for (int k = 0; k < keyList.size(); k++) {
                                JSONObject keyMap = keyList.getJSONObject(k);
                                String formId = keyMap.getString("F_FormId");
                                Integer type = keyMap.getInteger("F_Type");
                                JSONObject map = nwfTaskService.getStartTaskForm(keyMap, formId, startActivitiId, nwfSchemeInfoId, processInstanceId, deployId);
                                XjrFormSchemeInfo xjrFormSchemeInfo = formSchemeInfoService.getById(formId);
                                if (type == 2) {
                                    xjrFormSchemeInfo.setUrlAddress(formSchemeInfoService.getFullUrlOfSystemForm(formId));
                                }
                                if (xjrFormSchemeInfo != null) {
                                    map.put("SchemeInfo", BeanUtil.copy(xjrFormSchemeInfo, FormSchemeInfoVo.class));
                                }
                                // 表单字段信息
                                for (int i = 0; i < jsonArray.size(); i++) {
                                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                                    String fId = jsonObject.getString("F_Id");
                                    String fType = jsonObject.getString("F_Type");
                                    if (StringUtil.equals(formId, fId)) {
                                        if (StringUtil.equals(fType, "2")) {
                                            String fullUrlOfSystemForm = formSchemeInfoService.getFullUrlOfSystemForm(fId);
                                            jsonObject.put("F_Url", fullUrlOfSystemForm);
                                        }
                                        JSONArray childrens = jsonObject.getJSONArray("children");
                                        Iterator<Object> iter = childrens.iterator();
                                        while (iter.hasNext()) {
                                            Object next = iter.next();
                                            JSONObject children = JSONObject.parseObject(JSON.toJSONString(next));
                                            if (!children.getBoolean("view")) {
                                                iter.remove();
                                            }
                                        }
                                        map.put("formFieldInfo", jsonObject);
                                    }
                                }
                                // 获取审批意见内容
                                map.put("taskComment", FlowableUtil.getProcessInstanceComment(processInstanceId));
                                // 关联流程的信息
                                XjrBaseTempfield xjrBaseTempfield1 = tempfieldService.getByIdAndType(deployId + StringPool.UNDERSCORE + processInstanceId, "6");
                                map.put("relationTaskList", xjrBaseTempfield1 != null ? JSON.parse(xjrBaseTempfield1.getFvalue()) : "");
                                retList.add(map);
                            }
                        }
                    }
                }
            }
            ArrayList<String> assignees = nwfTaskMapper.getUserIdByTask(taskId);
            if (assignees.contains(currentUserId)) {
                taskInstancesList.add(historicTaskInstance);
            }
        } else if (historicTaskInstance != null) {
            taskInstancesList.add(historicTaskInstance);
        }
        for (HistoricTaskInstance taskInstance : taskInstancesList) {
            String key = nwfSchemeInfoId + StringPool.UNDERSCORE + taskInstance.getTaskDefinitionKey() + StringPool.UNDERSCORE + version;
            XjrBaseTempfield xjrBaseTempfield = xjrBaseTempfieldService.getByIdAndType(key, "3");
            if (xjrBaseTempfield == null || StringUtil.isBlank(xjrBaseTempfield.getFvalue())) {
                continue;
            }
            JSONArray jsonArray = JSON.parseArray(xjrBaseTempfield.getFvalue());
            String taskInstanceId = taskInstance.getId();
            ArrayList<String> assignees = new ArrayList<>();
            //是否是会签
            if (FlowableUtil.isMultiInstance(taskInstanceId)) {
                assignees.add(taskInstance.getAssignee());
            }
            assignees.addAll(FlowableUtil.getManualUser(processInstanceId, taskInstance.getTaskDefinitionKey()));
            assignees.addAll(nwfTaskMapper.getUserIdByTask(taskInstance.getId()));
            if (StringUtil.equals(isMyTask, "false") || assignees.contains(currentUserId)) {
                List<String> formIds = Arrays.asList(FlowableUtil.readTaskForm(taskInstance.getId()));
                // 获取任务表单key
                for (String formId : formIds) {
                    JSONObject map = new JSONObject();
                    // 查询节点信息
                    // 获取表单信息
                    if (StringUtil.isBlank(formId)) {
                        continue;
                    }
                    XjrFormSchemeInfo xjrFormSchemeInfo = formSchemeInfoService.getById(formId);
                    if (xjrFormSchemeInfo == null) {
                        continue;
                    }
                    Integer formtype = xjrFormSchemeInfo.getType();
                    if (formtype == 2) {
                        xjrFormSchemeInfo.setUrlAddress(formSchemeInfoService.getFullUrlOfSystemForm(formId));
                    }
                    String fSchemeid = xjrFormSchemeInfo.getSchemeId();
                    // 表单配置
                    XjrFormScheme xjrFormScheme = formSchemeService.getById(fSchemeid);
                    if (xjrFormScheme != null) {
                        JSONObject content = JSON.parseObject(xjrFormScheme.getScheme());
                        map.put("F_Scheme", content);
//                        }
                    }
                    // 表单字段信息
                    for (int j = 0; j < jsonArray.size(); j++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(j);
                        String fId = jsonObject.getString("F_Id");
                        String fType = jsonObject.getString("F_Type");
                        if (StringUtil.equals(formId, fId)) {
                            if (StringUtil.equals(fType, "2")) {
                                String fullUrlOfSystemForm = formSchemeInfoService.getFullUrlOfSystemForm(fId);
                                jsonObject.put("F_Url", fullUrlOfSystemForm);
                            }
                            JSONArray childrens = jsonObject.getJSONArray("children");
                            Iterator<Object> iter = childrens.iterator();
                            while (iter.hasNext()) {
                                Object next = iter.next();
                                JSONObject children = JSONObject.parseObject(JSON.toJSONString(next));
                                if (!children.getBoolean("view")) {
                                    iter.remove();
                                }
                            }
                            map.put("formFieldInfo", jsonObject);
                            break;
                        }
                    }
                    // 该表单的dataId
                    Map<String, Object> formData = null;
                    String dataId = "";
                    if (StringUtils.isNotBlank(startBusinessKey)) {
                        JSONArray keyList = JSONObject.parseArray(startBusinessKey);
                        for (int k = 0; k < keyList.size(); k++) {
                            JSONObject keyMap = keyList.getJSONObject(k);
                            if (StringUtils.equalsIgnoreCase(keyMap.getString("F_FormId"), formId)) {
                                dataId = keyMap.getString("F_Id");
                                if (formtype == 0) {
                                    if (StringUtil.isNotBlank(dataId) && StringUtil.isNotBlank(formId)) {
                                        formData = formSchemeInfoService.getCustomFormData(formId, dataId);
                                        break;
                                    }
                                } else {
                                    String urlAddress = keyMap.getString("F_UrlAddress");
                                    if (StringUtil.isNotBlank(dataId) && StringUtil.isNotBlank(urlAddress)) {
                                        formData = FlowableUtil.getSystemFormData(dataId, urlAddress);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (historicTaskInstance != null && historicTaskInstance.getEndTime() == null) {
                        JSONObject parameterValue = FlowableUtil.callActivityParameters(formData, taskInstance.getTaskDefinitionKey(), formId, nwfSchemeInfoId, processInstanceId);
                        parameterValue = FlowableUtil.processParameters(formData, taskInstance.getTaskDefinitionKey(), formId, nwfSchemeInfoId, processInstanceId, parameterValue);
                        if (CollectionUtil.isNotEmpty(parameterValue)) {
                            map.put("parameter", parameterValue);
                        }
                    }
                    map.put("formData", formData);
                    // 获取表单的数据
                    map.put("primaryKey", dataId);
                    map.put("SchemeInfo", BeanUtil.copy(xjrFormSchemeInfo, FormSchemeInfoVo.class));
                    // 获取审批意见内容
                    map.put("taskComment", FlowableUtil.getProcessInstanceComment(processInstanceId));
                    // 关联流程的信息
                    XjrBaseTempfield relationTasktempfield = tempfieldService.getByIdAndType(deployId + StringPool.UNDERSCORE + processInstanceId, "6");
                    map.put("relationTaskList", relationTasktempfield != null ? JSON.parse(relationTasktempfield.getFvalue()) : "");
                    boolean flag = false;
                    for (int i = 0; i < retList.size(); i++) {
                        JSONObject jsonObject = retList.getJSONObject(i);
                        String fId = jsonObject.getJSONObject("SchemeInfo").getString("id");
                        if (StringUtil.equals(fId, formId)) {
                            flag = true;
                            JSONObject formFieldInfo = jsonObject.getJSONObject("formFieldInfo");
                            JSONArray childrens1 = new JSONArray();
                            if (formFieldInfo != null) {
                                childrens1 = formFieldInfo.getJSONArray("children");
                            }
                            JSONObject formFieldInfo1 = map.getJSONObject("formFieldInfo");
                            JSONArray childrens2 = new JSONArray();
                            if (formFieldInfo1 != null) {
                                childrens2 = formFieldInfo1.getJSONArray("children");
                            }
                            if (CollectionUtil.isNotEmpty(childrens2)) {
                                for (int j = 0; j < childrens2.size(); j++) {
                                    JSONObject children2 = childrens2.getJSONObject(j);
                                    boolean flag2 = false;
                                    if (CollectionUtil.isNotEmpty(childrens1)) {
                                        for (int k = 0; k < childrens1.size(); k++) {
                                            JSONObject children1 = childrens1.getJSONObject(k);
                                            if (StringUtil.equals(children1.getString("bindTable"), children2.getString("bindTable")) && StringUtil.equals(children1.getString("fieldsId"), children2.getString("fieldsId"))) {
                                                flag2 = true;
                                            }
                                        }
                                    }
                                    if (!flag2) {
                                        childrens1.add(children2);
                                    }
                                }
                            }
                        }
                    }
                    if (!flag) {
                        retList.add(map);
                    }
                }
            }
        }
        if (CollectionUtil.isEmpty(retList)) {
            return Response.notOk("任务未绑定表单或者未参与该流程");
        } else {
            return Response.ok(retList);
        }
    }

    @PostMapping("/form-process")
    @ApiOperation(value = "表单发起流程信息")
    public Response getFormProcess(@RequestBody JSONObject jsonObject) {
        // 当前登录用户Id
        // 获取任务表单key
        JSONArray retList = new JSONArray();
        JSONObject map = new JSONObject();
        // 获取表单信息
        String formId = jsonObject.getString("F_FormId");
        Integer type = jsonObject.getInteger("F_Type");
        String nwfSchemeinfoId = jsonObject.getString("nwfSchemeinfoId");
        // 表单数据
        // 该表单的dataId
        String dataId = jsonObject.getString("F_Id");
        Map<String, Object> formData = null;
        if (type == 0) {
            formData = formSchemeInfoService.getCustomFormData(formId, dataId);
        } else {
            String urlAddress = jsonObject.getString("F_UrlAddress");
            formData = FlowableUtil.getSystemFormData(dataId, urlAddress);
        }
        map.put("formId", formId);
        map.put("fType", type);
        map.put("formData", formData);
        // 获取流程模板的数据
        XjrNwfSchemeinfo xjrNwfSchemeinfo = nwfschemeinfoService.getById(nwfSchemeinfoId);
        if (xjrNwfSchemeinfo != null) {
            NwfSchemeInfoVo nwfSchemeInfoVo = BeanUtil.copy(xjrNwfSchemeinfo, NwfSchemeInfoVo.class);
            XjrBaseDataItemDetail xjrBaseDataItemDetail = dataItemDetailService.getById(xjrNwfSchemeinfo.getCategory());
            nwfSchemeInfoVo.setCategory(xjrBaseDataItemDetail == null ? "" : xjrBaseDataItemDetail.getItemName());
            map.put("nwfSchemeInfo", nwfSchemeInfoVo);
        }
        retList.add(map);
        return Response.ok(retList);
    }


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/3
     * @Param:[taskId, userJson, map]
     * @return:com.xjrsoft.common.result.Response
     * @Description:处理任务接口
     */
    @PostMapping("/task-handle")
    @ApiOperation(value = "处理任务接口")
    @SneakyThrows
    public Response taskHandle(@RequestBody JSONObject parameter) throws Exception {
        Map<String, Object> retMap = FlowableUtil.completeTask(SecureUtil.getUserId(), parameter);
        return Response.ok(retMap);
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/3
     * @Param:[taskId, userJson, map]
     * @return:com.xjrsoft.common.result.Response
     * @Description:批量处理任务接口
     */
    @PostMapping("/batch-task-handle")
    @ApiOperation(value = "批量处理任务接口")
    @SneakyThrows
    public Response batchTaskHandle(@RequestBody JSONObject parameters) throws Exception {
        JSONArray result = new JSONArray();
        String userId = SecureUtil.getUserId();
        if (CollectionUtil.isNotEmpty(parameters)) {
            String btnValue = StringUtil.equals(parameters.getString("btnValue"), "agree_") ? "agree_" : "disagree_";
            JSONArray taskIdArray = parameters.getJSONArray("taskId");
            //审批意见
            String message = parameters.getString("message");
            // 签章ID
            String esignature = parameters.getString("esignature");
            // 签章密码
            String esignaturePwd = parameters.getString("esignature_pwd");
            if (CollectionUtil.isNotEmpty(taskIdArray)) {
                for (int i = 0; i < taskIdArray.size(); i++) {
                    JSONObject parameter = new JSONObject();
                    String taskId = taskIdArray.getString(i);
                    parameter.put("message", message);
                    parameter.put("esignature", esignature);
                    parameter.put("esignature_pwd", esignaturePwd);
                    parameter.put("btnValue", btnValue);
                    parameter.put("taskId", taskId);
                    JSONObject jsonObject = new JSONObject();
                    String approveInfo = "";
                    boolean isSuccess = false;
                    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
                    if (task != null) {
                        XjrBaseUser user = userService.getById(userId);
                        if (user != null) {
                        String  btnValue2= StringUtil.equals(parameters.getString("btnValue"), "agree_") ? "同意" : "拒绝";
                            approveInfo = StringPool.LEFT_BO_SQ_BRACKET + user.getRealName() + StringPool.RIGHT_BO_SQ_BRACKET + StringPool.LEFT_BO_SQ_BRACKET + btnValue2 + StringPool.RIGHT_BO_SQ_BRACKET + "审批" + StringPool.SEMICOLON + "由" + StringPool.LEFT_BO_SQ_BRACKET + task.getName() + StringPool.RIGHT_BO_SQ_BRACKET + "流转到";
                        }
                    }
                    try {
                        Map<String, Object> retMap = FlowableUtil.completeTask(SecureUtil.getUserId(), parameter);
                        Object retCode = retMap.get("retCode");
                        String value = String.valueOf(retCode);
                        if (StringUtil.equals(value, "0")) {
                            //审批成功
                            isSuccess = true;
                            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                            if (historicProcessInstance != null) {
                                if (historicProcessInstance.getEndTime() == null) {
                                    List<ActivityInstance> list = runtimeService.createActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).unfinished().list();
                                    if (CollectionUtil.isNotEmpty(list)) {
                                            approveInfo = approveInfo + StringPool.LEFT_BO_SQ_BRACKET + list.get(0).getActivityName() + StringPool.RIGHT_BO_SQ_BRACKET;
                                    }
                                } else {
                                    String endActivityId = historicProcessInstance.getEndActivityId();
                                    HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).activityId(endActivityId).singleResult();
                                    approveInfo = approveInfo + StringPool.LEFT_BO_SQ_BRACKET + historicActivityInstance.getActivityName() + StringPool.RIGHT_BO_SQ_BRACKET + StringPool.SEMICOLON;
                                }
                                approveInfo = approveInfo + "审批意见为" + StringPool.COLON + StringPool.LEFT_BO_SQ_BRACKET + parameter.getString("message") + StringPool.RIGHT_BO_SQ_BRACKET;
                            }
                        } else if (StringUtil.equals(value, "1")) {
                            approveInfo = "失败原因" + StringPool.COLON + "签章密码错误";
                        } else if (StringUtil.equals(value, "2")) {
                            approveInfo = "失败原因" + StringPool.COLON + "未设置审批人";
                        }
                    } catch (Exception e) {
                        approveInfo = "失败原因" + StringPool.COLON + e.getMessage();
                    }
                    jsonObject.put("taskId", taskId);
                    jsonObject.put("approveInfo", approveInfo);
                    jsonObject.put("isSuccess", isSuccess);
                    result.add(jsonObject);
                }
            }
        }
        return Response.ok(result);
    }


    @PostMapping("/get-stamp-info")
    @ApiOperation(value = "批量审批l获取签章信息")
    public Response getStamps(@RequestBody List<String> taskIds) {
        JSONObject result = new JSONObject();
        boolean needStamp = false;
        boolean needpassword = false;
        for (String taskId : taskIds) {
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
            String processDefinitionId = historicTaskInstance.getProcessDefinitionId();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
            if (processDefinition != null) {
                String key = processDefinition.getDescription() + StringPool.UNDERSCORE + historicTaskInstance.getTaskDefinitionKey() + StringPool.UNDERSCORE + String.valueOf(processDefinition.getVersion());
                XjrBaseTempfield xjrBaseTempfield = xjrBaseTempfieldService.getByIdAndType(key, "5");
                if (xjrBaseTempfield != null) {
                    JSONObject jsonObject = JSON.parseObject(xjrBaseTempfield.getFvalue());
                    //是否关联表单
                    Integer relationformem = jsonObject.getInteger("relationformem");
                    Integer needpassword1 = jsonObject.getInteger("needpassword");
                    if (relationformem == 1) {
                        //需要签章
                        needStamp = true;
                    }
                    if (needpassword1 == 2) {
                        needpassword = true;
                    }
                }
            }
        }
        result.put("needStamp", needStamp);
        result.put("needpassword", needpassword);
        return Response.ok(result);
    }


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/9
     * @Param:[taskId, processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取传阅任务信息
     */
    @GetMapping("/get-manualinfo")
    @ApiOperation(value = "获取传阅任务信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "任务id"),
            @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id")
    })
    public Response getManualInfo(String taskId, String processInstanceId) {
        List<Map<String, Object>> manualInfo = FlowableUtil.getManualInfo(taskId, processInstanceId);
        return Response.ok(manualInfo);
    }


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/9
     * @Param:[processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取已经流转过的节点的集合
     */
    @GetMapping("/finished-task/{processInstanceId}")
    @ApiOperation(value = "获取已经流转过的节点的集合")
    @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id")
    public Response getFinishedTask(@PathVariable("processInstanceId") String processInstanceId) {
        return Response.ok(FlowableUtil.getFinishedTask(processInstanceId));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:流程实例放入回收站
     */
    @DeleteMapping("/to-recyclebin/{processInstanceId}")
    @ApiOperation(value = "流程实例放入回收站")
    @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id")
    public Response toRecycleBin(@PathVariable("processInstanceId") String processInstanceId) throws Exception {
        return Response.status(FlowableUtil.toRecycleBin(processInstanceId));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[dto, fName]
     * @return:com.xjrsoft.common.result.Response
     * @Description:查询回收站
     */
    @GetMapping("/recycle-task")
    @ApiOperation(value = "查询回收站")
    public Response selectRecycleBin(GetPageListNwfTaskDto dto) {
        return Response.ok(FlowableUtil.selectRecycleBin(dto));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[taskId, isMyTask:是否从 我的任务 里发起的]
     * @return:void
     * @Description:撤回流程
     */
    @PutMapping("/recall-process")
    @ApiOperation(value = "撤回流程")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "任务id"),
            @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id")
    })
    public Response recallProcess(String taskId, String processInstanceId) throws Exception {
        // 获取当前的登录用户
        return Response.status(nwfTaskService.recallProcess(taskId, processInstanceId));
    }


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[taskId,
     * @return:void
     * @Description:流程中审批过的节点
     */
    @SneakyThrows
    @GetMapping("/process-mytask")
    @ApiOperation(value = "流程中审批过的节点")
    @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "任务id")
    public Response getProcessTask(String taskId) throws Exception {
        // 获取当前的登录用户
        return Response.ok(nwfTaskService.getProcessTask(taskId, SecureUtil.getUserId()));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:重新发起
     */
    @PostMapping("/reinitiate-process")
    @ApiOperation(value = "重新发起")
    public Response reinitiate(@RequestBody() Map<String, String> param) {
        return Response.ok(FlowableUtil.reinitiate(param.get("processInstanceId")));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:查询所有的流程实例
     */
    @GetMapping("/allprocess-list")
    @ApiOperation(value = "查询所有的流程实例")
    public Response listAllProcess(GetPageListDto dto) {
        return Response.ok(FlowableUtil.listAllProcess(dto));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[deploymentId, processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:测试修改流程版本
     */
    @PostMapping("/change-processversion-test")
    @ApiOperation(value = "测试修改流程版本")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id"),
            @ApiImplicitParam(name = "deploymentId", dataType = "string", paramType = "query", value = "流程部署id")
    })
    @SneakyThrows
    public Response testChangeProcessVersion(String deploymentId, String processInstanceId) {
        return Response.ok(FlowableUtil.testChangeProcessVer(processInstanceId, deploymentId));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[deploymentId, processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:修改流程版本
     */
    @GetMapping("/get-allprocess/{deploymentId}")
    @ApiOperation(value = "获取所有流程")
    @SneakyThrows
    @ApiImplicitParam(name = "deploymentId", dataType = "string", paramType = "query", value = "流程部署id")
    public Response getAllProcessId(@PathVariable("deploymentId") String deploymentId) {
        return Response.ok(nwfTaskService.getAllProcessId(deploymentId));
    }


    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/10
     * @Param:[deploymentId, processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:修改流程版本
     */
    @PutMapping("/change-processversion")
    @ApiOperation(value = "修改流程版本")
    @SneakyThrows
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id"),
            @ApiImplicitParam(name = "deploymentId", dataType = "string", paramType = "query", value = "流程部署id")
    })
    public Response changeProcessVersion(@RequestParam("deploymentId") String deploymentId, @RequestParam("processInstanceId") String processInstanceId) throws Exception {
        return Response.ok(nwfTaskService.changeProcessVersion(deploymentId, processInstanceId));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2020/11/9
     * @Param:[taskId, processInstanceId]
     * @return:void
     * @Description:验证流程是否允许加签
     */
    @GetMapping("validate-signation")
    @ApiOperation(value = "验证流程是否允许加签")
    @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "流程任务id")
    public Response validateSignation(String taskId) {
        boolean validateSignation = FlowableUtil.validateSignation(taskId);
        boolean multiInstance = FlowableUtil.isMultiInstance(taskId);
        if (validateSignation && multiInstance) {
            return Response.ok(true);
        } else {
            return Response.ok(false);
        }
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/4
     * @Param:[taskId, processInstanceId, userListStr]
     * @return:com.xjrsoft.common.result.Response
     * @Description:加签/减签
     */
    @PostMapping("/signature")
    @ApiOperation(value = "加签/减签")
    public Response signature(@RequestBody JSONObject parameter) {
        XjrUser currentUser = SecureUtil.getUser();
        JSONArray userList = JSON.parseArray(parameter.getString("userListStr"));
        return Response.status(FlowableUtil.signature(parameter.getString("taskId"), userList, currentUser));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/29
     * @Param:[taskId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取会签任务的审批人员
     */
    @GetMapping("candidate-users")
    @ApiOperation(value = "获取会签任务的审批人员")
    @ApiImplicitParam(name = "processInstanceId", dataType = "String", paramType = "query", value = "流程实例id")
    public Response getCandidateUsers(String processInstanceId) {
        return Response.ok(BeanUtil.copyList(FlowableUtil.getMultiInstanceTaskCandidateUser(processInstanceId), UserVo.class));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/18
     * @Param:[dto]
     * @return:void
     * @Description:获取关联流程列表
     */
    @GetMapping("/relationTask")
    @ApiOperation(value = "获取关联任务列表")
    public Response getRelationTask(GetPageListNwfTaskDto dto) {
        return Response.ok(nwfTaskService.getRelationTask(dto, SecureUtil.getUserId()));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/28
     * @Param:[processInstanceId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取关联流程信息
     */
    @GetMapping("/relationTask-Info")
    @ApiImplicitParam(name = "processInstanceId", dataType = "String", paramType = "query", value = "流程实例id")
    public Response getRelationTaskInfo(String processInstanceId) {
        return Response.ok(nwfTaskService.getRelationTaskInfo(processInstanceId));
    }


    //删除流程实例
    @DeleteMapping("/delete-processinstance/{processInstanceId}")
    @ApiOperation(value = "删除流程实例")
    @ApiImplicitParam(name = "processInstanceId", dataType = "String", paramType = "query", value = "流程实例id")
    public Response deleteProcessInstance(@PathVariable("processInstanceId") String processInstanceId) {
        return Response.ok(FlowableUtil.deleteProcessInstance(processInstanceId));
    }

    //获取附件信息
    @GetMapping("/getAnnexInfo")
    @ApiOperation(value = "获取附件列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query", value = "流程实例id"),
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "流程任务id")
    })
    public Response getAnnexInfo(@RequestParam("processInstanceId") String
                                         processInstanceId, @RequestParam(value = "taskId") String taskId) {
        return Response.ok(FlowableUtil.getAnnexInfo(processInstanceId, taskId));
    }

    //保存草稿
    @PostMapping("/saveOrEditTempfiledInfo")
    @ApiOperation(value = "保存或编辑草稿")
    public Response saveOrEditTempfiledInfo(@RequestBody JSONObject parameter) throws Exception {
        return Response.status(nwfTaskService.saveOrEditTempfiledInfo(parameter));
    }

    //获取草稿列表
    @GetMapping("/getTempfiledInfoList")
    @ApiOperation(value = "获取草稿列表")
    public Response getTempfiledInfoList(GetPageListNwfTaskDto dto) {
        return Response.ok(nwfTaskService.getTempfiledInfoList(dto));
    }

    //获取草稿列表
    @DeleteMapping("/delete-tempfiledInfo/{fId}")
    @ApiOperation(value = "删除草稿")
    @ApiImplicitParam(name = "fId", dataType = "string", paramType = "query", value = "流程草稿id")
    public Response deleteTempfiledInfo(@PathVariable("fId") String fId) {
        return Response.ok(nwfTaskService.deleteTempfiledInfo(fId));
    }

    @GetMapping("/getTaskInfo")
    @ApiOperation(value = "获取任务信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "operation", dataType = "string", paramType = "query", value = "操作 1:审批操作,2:传阅操作"),
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "流程任务id")
    })
    public Response getTaskInfo(@RequestParam("taskId") String taskId, @RequestParam("operation") String operation) throws
            Exception {
        return Response.ok(nwfTaskService.getTaskInfo(taskId, operation));
    }

    @PutMapping("/change-candidate")
    @ApiOperation(value = "转办")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "newUserId", dataType = "string", paramType = "query", value = "转办用户的id"),
            @ApiImplicitParam(name = "oldUserId", dataType = "string", paramType = "query", value = "之前用户的id"),
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "流程任务id")
    })
    public Response changeCandidate(@RequestParam("taskId") String taskId, @RequestParam("oldUserId") String
            oldUserId, @RequestParam("newUserId") String newUserId) throws Exception {
        return Response.ok(nwfTaskService.changeCandidate(taskId, newUserId, oldUserId));
    }

    @PostMapping("/again-candidate")
    @ApiOperation(value = "再次设置审批人")
    public Response againCandidate(@RequestBody JSONArray jsonArray) throws Exception {
        return Response.status(nwfTaskService.againCandidate(jsonArray));
    }

    @PutMapping("/read/{taskId}")
    @ApiOperation(value = "设置已阅")
    @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query", value = "流程任务id")
    public Response read(@PathVariable("taskId") String taskId) {
        return Response.status(nwfTaskService.read(taskId));
    }

    @DeleteMapping("/deleteUselessDate")
    @ApiOperation(value = "删除无用的流程数据")
    public Response deleteUselessDate() {
        return Response.ok(nwfTaskService.deleteUselessDate());
    }

}
